package com.rejuvee.myloginapplication.ui.login;

import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.rejuvee.myloginapplication.R;
import com.rejuvee.myloginapplication.data.model.LoggedInUserView;
import com.rejuvee.myloginapplication.databinding.ActivityLoginBinding;
import com.rejuvee.myloginapplication.ui.login.vm.LoginViewModel;
import com.rejuvee.myloginapplication.ui.login.vm.LoginViewModelFactory;

public class LoginActivity extends AppCompatActivity {
    // 数据模型
    private LoginViewModel loginViewModel;
    // 视图绑定
    private ActivityLoginBinding binding;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 把布局文件绑定到Activity
        binding = ActivityLoginBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        // 绑定数据模型
        loginViewModel = new ViewModelProvider(this, new LoginViewModelFactory()).get(LoginViewModel.class);

        // 寻找组件，等同于老方法findViewById()
        final EditText usernameEditText = binding.username;// 输入框-账号
        final EditText passwordEditText = binding.password;// 输入框-密码
        final Button loginButton = binding.login;// 按钮登陆按钮
        final ProgressBar loadingProgressBar = binding.loading;//加载状态指示器

        // 表单验证监听：
        // **每一次loginFormState的值变化   （observe 观察者）都会回调触发这里
        loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
            @Override
            public void onChanged(@Nullable LoginFormState loginFormState) {
                if (loginFormState == null) {
                    //第一次null，直接返回
                    return;
                }
                // 登陆按钮是否可以点击（假如没有表单输入错误，就是可以点击的）
                loginButton.setEnabled(loginFormState.isDataValid());
                // 如果用户名输入错误
                if (loginFormState.getUsernameError() != null) {
                    // 输入框红字提示错误
                    usernameEditText.setError(getString(loginFormState.getUsernameError()));
                }
                // 如果密码输入错误
                if (loginFormState.getPasswordError() != null) {
                    //输入框红字提示密码错误
                    passwordEditText.setError(getString(loginFormState.getPasswordError()));
                }
            }
        });

        // 登陆结果监听：
        // **每一次loginFormResult的值变化（observe 观察者）都会回调触发这里
        loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
            @Override
            public void onChanged(@Nullable LoginResult loginResult) {
                if (loginResult == null) {
                    //第一次null，直接返回
                    return;
                }
                // 隐藏加载状态指示器
                loadingProgressBar.setVisibility(View.GONE);
                // 包含登录结果-错误
                if (loginResult.getError() != null) {
                    // 提示错误信息
                    showLoginFailed(loginResult.getError());
                }
                // 包含登录结果-成功
                if (loginResult.getLoggedInUserView() != null) {
                    // 提示成功信息（界面应该显示用户名了）
                    updateUiWithUser(loginResult.getLoggedInUserView());
                    // 登录成功时，销毁当前activity
                    // TODO 应该改成跳转至新activity
//                    finish();
                }
            }
        });

        // 字符改变监听器 （每次输入、删除字符都会触发）
        TextWatcher afterTextChangedListener = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // 字符改变之前 无需处理
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // 字符改变之时 无需处理
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 字符改变之后 需要处理
                loginViewModel.loginDataChanged(
                        // 获取输入框-账号的当前值
                        usernameEditText.getText().toString(),
                        // 获取输入框-密码的当前值
                        passwordEditText.getText().toString());
            }
        };
        // 给用 用户名输入框 添加字符改变监听器(字符一改变就触发)
        usernameEditText.addTextChangedListener(afterTextChangedListener);
        // 给用 密码输入框 添加字符改变监听器(字符一改变就触发)
        passwordEditText.addTextChangedListener(afterTextChangedListener);
        // 给密码输入框添加软键盘监听 （编辑完之后点击软键盘上的各种键才会触发）
        passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                // 这里判断如果是点击的[完成键]，就进行登录的动作
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    // 使用用户名密码尝试登录
                    loginViewModel.login(
                            // 获取输入框-账号的当前值
                            usernameEditText.getText().toString(),
                            // 获取输入框-密码的当前值
                            passwordEditText.getText().toString());
                }
                //  返回false表示点击后，隐藏软键盘。返回true表示保留软键盘。
                return false;
            }
        });

        // 给登陆按钮添加点击监听
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //显示加载状态指示器
                loadingProgressBar.setVisibility(View.VISIBLE);
                // 使用用户名密码尝试登录
                loginViewModel.login(
                        // 获取输入框-账号的当前值
                        usernameEditText.getText().toString(),
                        // 获取输入框-密码的当前值
                        passwordEditText.getText().toString());
                Intent intent = new Intent();
                intent.setClass(LoginActivity.this,MainActivity.class);
                intent.putExtra("username",usernameEditText.getText().toString());
                startActivity(intent);
            }
        });
    }

    /**
     * 界面中更新用户信息
     *
     * @param model
     */
    private void updateUiWithUser(LoggedInUserView model) {
        // 欢迎+用户名
        String welcome = getString(R.string.welcome) + model.getDisplayName();
        // 弹出提示
        Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
    }

    /**
     * 界面中提示错误信息
     *
     * @param errorString 错误信息文字 资源ID
     */
    private void showLoginFailed(@StringRes Integer errorString) {
        // 弹出提示
        Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
    }
}